#include "net/socket.h"
#include "net/socket_opt.h"

#include <sstream>
#include <netinet/in.h>

namespace net {
Addr::Addr(const std::string&ip, uint16 port) {
  ::memset(&addr, 0, sizeof(addr));
  addr.sin_family = AF_INET;
  addr.sin_port = htons(port);
  if (ip.empty() || ip == "0" || ip == "0.0.0.0") {
    addr.sin_addr.s_addr = INADDR_ANY;
    return;
  }

  addr.sin_addr.s_addr = StrToIp(ip);
}

const std::string Addr::DebugString() const {
  std::stringstream ss;
  ss << "ip: " << IpToStr(addr.sin_addr.s_addr) << "\t" << "port: "
     << ntohs(addr.sin_port);
  return ss.str();
}

Socket::Socket()
    : fd_(sock::CreateSocket()) {
  CHECK(fd_ != -1);
}

Socket::~Socket() {
  sock::Close(fd_);
}

bool Socket::Listen(const Addr& addr) {
  if (!sock::Bind(this, addr) || !sock::Listen(this)) {
    return false;
  }

  sock::GetSockAddr(this, true);
  LOG(INFO)<< "listen addr: " << local_addr_.DebugString();

  return true;
}

int32 Socket::Accept(Addr* addr) {
  return sock::Accept(this, addr);
}

bool Socket::Connect(const Addr& addr) {
  return sock::Connect(this, addr);
}

}
